package com.xueyi.workflow.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xueyi.common.core.constant.basic.SqlConstants;
import com.xueyi.workflow.domain.dto.WfProcessVersionDto;
import com.xueyi.workflow.domain.entity.WfProcessVersion;
import com.xueyi.workflow.domain.query.WfProcessVersionQuery;
import com.xueyi.workflow.manager.WfProcessVersionManager;
import com.xueyi.workflow.service.IWfProcessVersionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 流程版本Service业务层处理
 *
 * @author xueyi
 * @date 2024-07-03
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class WfProcessVersionServiceImpl implements IWfProcessVersionService {

    private final WfProcessVersionManager wfProcessVersionManager;
    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 查询流程版本详情
     */
    @Override
    public WfProcessVersionDto getProcessVersion(String processId, Integer version) {
        log.info("查询流程版本 - processId: {}, version: {}", processId, version);
        
        // 首先检查processId是否为数字格式（可能是流程版本ID）
        if (processId != null && processId.matches("\\d+")) {
            try {
                Long versionId = Long.valueOf(processId);
                log.info("processId {} 是数字格式，尝试作为流程版本ID查询", versionId);
                
                // 直接通过ID查询
                WfProcessVersionQuery idQuery = new WfProcessVersionQuery();
                idQuery.setId(versionId);
                List<WfProcessVersionDto> versions = wfProcessVersionManager.selectList(idQuery);
                
                if (!versions.isEmpty()) {
                    WfProcessVersionDto versionInfo = versions.get(0);
                    log.info("通过流程版本ID {} 找到流程信息: key={}, name={}, version={}", 
                        versionId, versionInfo.getProcessKey(), versionInfo.getProcessName(), versionInfo.getVersion());
                    
                    // 解析人员配置数据
                    if (versionInfo.getGraphSchema() != null) {
                        try {
                            Map<String, Object> graphData = objectMapper.readValue(versionInfo.getGraphSchema(),
                                new TypeReference<Map<String, Object>>() {});

                            // 提取人员配置信息
                            List<Map<String, Object>> assigneeConfig = extractAssigneeConfig(graphData);
                            versionInfo.setAssigneeConfig(assigneeConfig);

                            log.info("成功解析流程版本 {} 的人员配置，共 {} 个节点", versionInfo.getVersion(), assigneeConfig.size());
                        } catch (JsonProcessingException e) {
                            log.error("解析流程版本图形数据失败: {}", e.getMessage());
                            // 设置空的人员配置
                            versionInfo.setAssigneeConfig(new ArrayList<>());
                        }
                    }
                    
                    return versionInfo;
                } else {
                    log.warn("通过流程版本ID {} 未找到流程信息", versionId);
                }
            } catch (NumberFormatException e) {
                log.warn("processId {} 不是有效的数字格式", processId);
            }
        }
        
        // 如果不是数字格式或通过ID查询失败，使用原有的查询逻辑
        log.info("使用原有逻辑查询流程版本 - processId: {}, version: {}", processId, version);
        
        // 构建查询条件
        WfProcessVersionQuery query = new WfProcessVersionQuery();
        
        // 处理 processId，检查是否为数字格式
        if (processId != null && processId.matches("\\d+")) {
            // 如果是数字格式，通过 processId 查询
            try {
                Long processIdLong = Long.valueOf(processId);
                query.setProcessId(processIdLong);
                log.info("使用processId字段查询: {}", processIdLong);
            } catch (NumberFormatException e) {
                log.warn("processId {} 转换为Long失败，使用processKey查询", processId);
                query.setProcessKey(processId);
            }
        } else {
            // 如果不是数字格式，可能是流程名称或流程Key，尝试通过 processKey 查询
            query.setProcessKey(processId);
            log.info("使用processKey字段查询: {}", processId);
        }
        
        if (version != null) {
            query.setVersion(version);
        }

        // 查询数据库
        List<WfProcessVersionDto> versions = wfProcessVersionManager.selectList(query);
        log.info("查询到 {} 个流程版本", versions.size());

        // 根据条件过滤
        WfProcessVersionDto versionInfo = versions.stream()
                .filter(v -> {
                    // 如果processId是数字格式，通过processId字段过滤
                    if (processId != null && processId.matches("\\d+")) {
                        try {
                            Long processIdLong = Long.valueOf(processId);
                            boolean matches = v.getProcessId() != null && v.getProcessId().equals(processIdLong);
                            log.debug("过滤条件 - processId匹配: {} == {} = {}", v.getProcessId(), processIdLong, matches);
                            return matches;
                        } catch (NumberFormatException e) {
                            log.warn("processId {} 转换为Long失败", processId);
                            return false;
                        }
                    } else {
                        // 如果不是数字格式，通过processKey字段过滤
                        boolean matches = processId == null || v.getProcessKey().equals(processId);
                        log.debug("过滤条件 - processKey匹配: {} == {} = {}", v.getProcessKey(), processId, matches);
                        return matches;
                    }
                })
                .filter(v -> version == null || v.getVersion().equals(version))
                .findFirst()
                .orElse(null);
                
        if (versionInfo != null) {
            log.info("找到匹配的流程版本: key={}, name={}, version={}", 
                versionInfo.getProcessKey(), versionInfo.getProcessName(), versionInfo.getVersion());
            
            // 解析人员配置数据
            if (versionInfo.getGraphSchema() != null) {
                try {
                    Map<String, Object> graphData = objectMapper.readValue(versionInfo.getGraphSchema(),
                        new TypeReference<Map<String, Object>>() {});

                    // 提取人员配置信息
                    List<Map<String, Object>> assigneeConfig = extractAssigneeConfig(graphData);
                    versionInfo.setAssigneeConfig(assigneeConfig);

                    log.info("成功解析流程版本 {} 的人员配置，共 {} 个节点", versionInfo.getVersion(), assigneeConfig.size());
                } catch (JsonProcessingException e) {
                    log.error("解析流程版本图形数据失败: {}", e.getMessage());
                    // 设置空的人员配置
                    versionInfo.setAssigneeConfig(new ArrayList<>());
                }
            }
        } else {
            log.warn("未找到匹配的流程版本，processId: {}, version: {}", processId, version);
        }
        
        return versionInfo;
    }

    /**
     * 通过流程版本ID获取流程版本信息
     */
    @Override
    public WfProcessVersionDto getProcessVersionById(Long versionId) {
        log.info("通过流程版本ID查询流程版本信息: {}", versionId);
        
        if (versionId == null) {
            log.warn("流程版本ID为空");
            return null;
        }
        
        try {
            // 直接通过ID查询
            WfProcessVersionQuery idQuery = new WfProcessVersionQuery();
            idQuery.setId(versionId);
            List<WfProcessVersionDto> versions = wfProcessVersionManager.selectList(idQuery);
            
            if (!versions.isEmpty()) {
                WfProcessVersionDto versionInfo = versions.get(0);
                log.info("通过流程版本ID {} 找到流程信息: key={}, name={}, version={}", 
                    versionId, versionInfo.getProcessKey(), versionInfo.getProcessName(), versionInfo.getVersion());
                
                // 解析人员配置数据
                if (versionInfo.getGraphSchema() != null) {
                    try {
                        Map<String, Object> graphData = objectMapper.readValue(versionInfo.getGraphSchema(),
                            new TypeReference<Map<String, Object>>() {});

                        // 提取人员配置信息
                        List<Map<String, Object>> assigneeConfig = extractAssigneeConfig(graphData);
                        versionInfo.setAssigneeConfig(assigneeConfig);

                        log.info("成功解析流程版本 {} 的人员配置，共 {} 个节点", versionInfo.getVersion(), assigneeConfig.size());
                    } catch (JsonProcessingException e) {
                        log.error("解析流程版本图形数据失败: {}", e.getMessage());
                        // 设置空的人员配置
                        versionInfo.setAssigneeConfig(new ArrayList<>());
                    }
                }
                
                return versionInfo;
            } else {
                log.warn("通过流程版本ID {} 未找到流程信息", versionId);
                return null;
            }
        } catch (Exception e) {
            log.error("通过流程版本ID查询流程版本信息失败: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 查询流程版本详情（通过processKey）
     */
    @Override
    public WfProcessVersionDto getProcessVersionByKey(String processKey, Integer version) {
        // 构建查询条件
        WfProcessVersionQuery query = new WfProcessVersionQuery();
        query.setProcessKey(processKey);
        if (version != null) {
            query.setVersion(version);
        }

        // 查询数据库
        WfProcessVersionDto versionInfo = wfProcessVersionManager.selectList(query).stream()
                .filter(v -> v.getProcessKey().equals(processKey))
                .filter(v -> version == null || v.getVersion().equals(version))
                .findFirst()
                .orElse(null);

        if (versionInfo == null && version == null) {
            // 如果没有指定版本，查询最新版本
            versionInfo = wfProcessVersionManager.selectList(query).stream()
                    .filter(v -> v.getProcessKey().equals(processKey))
                    .max((v1, v2) -> Integer.compare(v1.getVersion(), v2.getVersion()))
                    .orElse(null);
        }

        // 如果找到了版本信息，解析人员配置数据
        if (versionInfo != null && versionInfo.getGraphSchema() != null) {
            try {
                Map<String, Object> graphData = objectMapper.readValue(versionInfo.getGraphSchema(),
                    new TypeReference<Map<String, Object>>() {});

                // 提取人员配置信息
                List<Map<String, Object>> assigneeConfig = extractAssigneeConfig(graphData);
                versionInfo.setAssigneeConfig(assigneeConfig);

                log.info("成功解析流程版本 {} 的人员配置，共 {} 个节点", versionInfo.getVersion(), assigneeConfig.size());
            } catch (JsonProcessingException e) {
                log.error("解析流程版本图形数据失败: {}", e.getMessage());
                // 设置空的人员配置
                versionInfo.setAssigneeConfig(new ArrayList<>());
            }
        }

        return versionInfo;
    }

    /**
     * 从VueFlow图形数据中提取人员配置信息
     */
    private List<Map<String, Object>> extractAssigneeConfig(Map<String, Object> graphData) {
        List<Map<String, Object>> assigneeConfig = new ArrayList<>();

        try {
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> nodes = (List<Map<String, Object>>) graphData.get("nodes");

            if (nodes != null) {
                for (Map<String, Object> node : nodes) {
                    String nodeType = (String) node.get("type");

                    // 只处理用户任务节点
                    if ("userTask".equals(nodeType) || "task".equals(nodeType)) {
                        @SuppressWarnings("unchecked")
                        Map<String, Object> nodeData = (Map<String, Object>) node.get("data");

                        if (nodeData != null) {
                            Map<String, Object> config = new HashMap<>();
                            config.put("id", node.get("id"));
                            config.put("name", nodeData.get("label"));
                            // 统一转换为大写格式，保持与旧版本的一致性
                            config.put("type", "USER_TASK");
                            config.put("assigneeType", nodeData.get("assigneeType"));
                            config.put("assigneeValue", nodeData.get("assigneeValue"));
                            config.put("countersign", nodeData.get("countersign"));

                            // 处理已配置的人员列表
                            @SuppressWarnings("unchecked")
                            List<Map<String, Object>> assignees = (List<Map<String, Object>>) nodeData.get("assignees");
                            if (assignees != null) {
                                config.put("assignees", assignees);
                            } else {
                                config.put("assignees", new ArrayList<>());
                            }

                            assigneeConfig.add(config);
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("提取人员配置信息失败: {}", e.getMessage());
        }

        return assigneeConfig;
    }

    /**
     * 获取流程最新版本号
     */
    @Override
    public Integer getLatestVersion(String processId) {
        // 构建查询条件
        WfProcessVersionQuery query = new WfProcessVersionQuery();
        
        // 处理 processId，检查是否为数字格式
        if (processId != null && processId.matches("\\d+")) {
            // 如果是数字格式，通过 processId 查询
            try {
                Long processIdLong = Long.valueOf(processId);
                query.setProcessId(processIdLong);
            } catch (NumberFormatException e) {
                log.warn("processId {} 转换为Long失败，使用processKey查询", processId);
                query.setProcessKey(processId);
            }
        } else {
            // 如果不是数字格式，可能是流程名称或流程Key，尝试通过 processKey 查询
            log.info("processId 不是数字格式: {}, 尝试通过 processKey 查询", processId);
            query.setProcessKey(processId);
        }

        // 查询数据库
        List<WfProcessVersionDto> versions = wfProcessVersionManager.selectList(query);

        if (versions.isEmpty()) {
            return 1; // 如果没有版本记录，返回默认版本号
        }

        // 返回最大版本号
        return versions.stream()
                .mapToInt(WfProcessVersionDto::getVersion)
                .max()
                .orElse(1);
    }

    /**
     * 获取流程最新版本号（通过processKey）
     */
    @Override
    public Integer getLatestVersionByKey(String processKey) {
        // 构建查询条件
        WfProcessVersionQuery query = new WfProcessVersionQuery();
        query.setProcessKey(processKey);

        // 查询数据库
        List<WfProcessVersionDto> versions = wfProcessVersionManager.selectList(query);

        if (versions.isEmpty()) {
            return 1; // 如果没有版本记录，返回默认版本号
        }

        // 返回最大版本号
        return versions.stream()
                .mapToInt(WfProcessVersionDto::getVersion)
                .max()
                .orElse(1);
    }
}
